package tgeo.common;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class DES {
	public static final int ENCRYPTION_MODE = 0;
	public static final int DECRYPTION_MODE = 1;

	public static final String ALGORITHM_DES = "DES";
	public static final String MODE_CBC = "CBC";
	public static final String MODE_ECB = "ECB";
	public static final String PADDING_PKCS5Padding = "PKCS5Padding";
	public static final String PADDING_NoPadding = "NoPadding";

	byte[] key = null;
	byte[] IV = null;
	String mode = "";
	String padmode = "";

	public DES(byte[] key, byte[] IV, String mode, String padmode) {
		this.key = key;
		this.mode = mode;
		this.IV = IV;
		this.padmode = padmode;
	}

	public byte[] encrypt(byte[] data) {
		byte[] ret = null;
		ret = encrypt(data, key, IV, ALGORITHM_DES, this.mode,
				this.padmode);
		return ret;
	}

	public byte[] decrypt(byte[] data) {
		byte[] ret = null;
		ret = decrypt(data, key, IV, ALGORITHM_DES, this.mode,
				this.padmode);
		return ret;
	}

	private byte[] encrypt(byte[] text, byte[] inKey, byte[] inIv,
			String algorithm, String mode, String padding) {
		if (text.length == 0 || inKey.length != 8) {
			return new byte[0];
		}
		byte[] rtnBytes = null;
		try {
			if (ALGORITHM_DES.equals(algorithm) && MODE_CBC.equals(mode)
					&& PADDING_PKCS5Padding.equals(padding)) {
				Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
				SecretKeySpec secretKeySpec = new SecretKeySpec(inKey, "DES");
				IvParameterSpec ivspec = new IvParameterSpec(inIv);

				cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec);
				rtnBytes = cipher.doFinal(text);
			} else if (ALGORITHM_DES.equals(algorithm) && MODE_CBC.equals(mode)
					&& PADDING_NoPadding.equals(padding)) {
				Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");
				SecretKeySpec secretKeySpec = new SecretKeySpec(inKey, "DES");
				IvParameterSpec ivspec = new IvParameterSpec(inIv);

				cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec);
				rtnBytes = cipher.doFinal(text);
			} else if (ALGORITHM_DES.equals(algorithm) && MODE_ECB.equals(mode)
					&& PADDING_PKCS5Padding.equals(padding)) {
				Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
				SecretKeySpec secretKeySpec = new SecretKeySpec(inKey, "DES");

				cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
				rtnBytes = cipher.doFinal(text);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rtnBytes;
	}

	private byte[] decrypt(byte[] text, byte[] inKey, byte[] inIv,
			String algorithm, String mode, String padding) {
		if (text.length == 0 || inKey.length != 8) {
			return new byte[0];
		}
		byte[] rtnBytes = null;
		try {
			if (ALGORITHM_DES.equals(algorithm) && MODE_CBC.equals(mode)
					&& PADDING_PKCS5Padding.equals(padding)) {
				Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
				SecretKeySpec secretKeySpec = new SecretKeySpec(inKey, "DES");
				IvParameterSpec ivspec = new IvParameterSpec(inIv);

				cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec);
				rtnBytes = cipher.doFinal(text);
			} else if (ALGORITHM_DES.equals(algorithm) && MODE_CBC.equals(mode)
					&& PADDING_NoPadding.equals(padding)) {
				Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");
				SecretKeySpec secretKeySpec = new SecretKeySpec(inKey, "DES");
				IvParameterSpec ivspec = new IvParameterSpec(inIv);

				cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec);
				rtnBytes = cipher.doFinal(text);
			} else if (ALGORITHM_DES.equals(algorithm) && MODE_ECB.equals(mode)
					&& PADDING_PKCS5Padding.equals(padding)) {
				Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
				SecretKeySpec secretKeySpec = new SecretKeySpec(inKey, "DES");

				cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
				rtnBytes = cipher.doFinal(text);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rtnBytes;
	}

	public static void main(String[] args) {
    	byte[] key = new byte[]{'1', '2', '3', '4', '1', '2', '3', '4'};
    	byte[] IV = new byte[]{'1', '1', '1', '1', '1', '1', '1', '1'};

		DES des = new DES(key, IV, MODE_CBC, PADDING_PKCS5Padding);
		byte [] encData = des.encrypt("abcd".getBytes());
		byte [] decData = des.decrypt(encData);
		System.out.println(new String(decData));
	}

}
